package rateexchange.client.mvp;

import java.util.Set;

import rateexchange.client.ClientFactory;
import rateexchange.client.place.RatePlace;
import rateexchange.client.place.RatesTablePlace;
import rateexchange.client.ui.RateEditor;
import rateexchange.client.ui.RateView;
import rateexchange.client.ui.RateViewImpl;
import rateexchange.shared.RateProxy;
import rateexchange.shared.RateRequest;
import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.Place;
import com.google.gwt.requestfactory.client.RequestFactoryEditorDriver;
import com.google.gwt.requestfactory.shared.Receiver;
import com.google.gwt.requestfactory.shared.Request;
import com.google.gwt.requestfactory.shared.RequestContext;
import com.google.gwt.requestfactory.shared.Violation;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AcceptsOneWidget;

//Presenter driving the RateView
@SuppressWarnings("deprecation")
public class RateActivity extends AbstractActivity implements RateView.RateHandler{
	
	//Driver interface connecting RateProxy with corresponding Editor
	interface Driver extends RequestFactoryEditorDriver<RateProxy, RateEditor>{}
	
	private ClientFactory 	clientfactory;
	
	private RatePlace 		place;
	
	private RateViewImpl 	impl;
	
	private Driver driver = GWT.create(Driver.class);
	
	public RateActivity(RatePlace place, ClientFactory clientfactory){
		this.clientfactory = clientfactory;
		this.place = place;
	}

	// Called to set the widget driven by this Activity and accumulate procedures to be fired
	@Override
	public void start(AcceptsOneWidget panel, EventBus eventBus) {
		//Instance the RateView
		impl = new RateViewImpl();
		impl.setPresenter(this);
		
		if(RatePlace.REQ.equals(place.getToken())){
			driver.initialize(clientfactory.getRequestFactory(), impl.getEditor());
			RateRequest req = clientfactory.getRequestFactory().raterequest();
			RateProxy rate = req.create(RateProxy.class);
			// edit returns a mutable version of the proxy, whose mutations will accumulate in this context.
			driver.edit(rate, req);
			req.persist().using(rate);
		} else if(RatePlace.RATE.equals(place.getToken())){
			Request<RateProxy> perReq = clientfactory.getRequestFactory().find(place.getRate().stableId());
			
//			perReq.with(driver.getPaths());
			
			perReq.to(new Receiver<RateProxy>() {

				@Override
				public void onSuccess(RateProxy rate) {
					driver.initialize(clientfactory.getRequestFactory(), impl.getEditor());
					RateRequest req = clientfactory.getRequestFactory().raterequest();
					driver.edit(rate, req);
					req.persist().using(rate);
					
				}
			}).fire();
		}
		
		
		panel.setWidget(impl);
		
	}
	
	
	
	@SuppressWarnings("deprecation")
	@Override
	public void save(){
		// Flush used with RequestFactoryEditorDriver returns the RequestContext handed over to driver when calling driver.edit(rate, req);
		RequestContext cont = driver.flush();
		if(driver.hasErrors()){
			Window.alert("Some error!");
		}
		// Request with all accumulated procedures will be fired on firing save()
		cont.fire(new Receiver<Void>() {

			@Override
			public void onSuccess(Void response) {
				RateActivity.this.goTo(new RatesTablePlace("list"));
				
			}
			
			public void onViolation (Set<Violation> errors){
				Window.alert("There is some error on server");
			}
			
            
		});
		
		
	}


	@Override
	public void goTo(Place place) {
		clientfactory.getPlaceController().goTo(place);
		
	}
}
